<script setup lang="ts">
import { computed, defineAsyncComponent, onMounted, ref, watch } from 'vue';
import { Collapse, CollapsePanel } from 'ant-design-vue';
import { utils, SearchCriteria } from '@xcan-angus/infra';
import { analysis } from '@/api/tester';

import { TaskCount } from '../../types';

/**
 * API request parameters interface
 */
interface RequestParams {
  projectId: number;
  filters?: SearchCriteria[];
}

/**
 * Component props interface for Statistics component
 */
type Props = {
  collapse: boolean;
  params: RequestParams;
  projectId: number;
  userInfo: { id: number };
  appInfo: { id: number };
  notify: string;
  moduleId?: number;
}

// Props and Emits Definition
const props = withDefaults(defineProps<Props>(), {
  collapse: false,
  params: undefined,
  projectId: undefined,
  userInfo: undefined,
  appInfo: undefined,
  notify: undefined,
  moduleId: undefined
});

const emit = defineEmits<{
  (e: 'update:loading', value: boolean): void;
}>();

/**
 * Lazy-loaded Count component for displaying statistics cards
 */
const Count = defineAsyncComponent(() => import('./Count.vue'));

/**
 * Lazy-loaded Chart component for displaying charts
 */
const Chart = defineAsyncComponent(() => import('@/views/issue/issue/list/statistics/Chart.vue'));

// Constants and State
const componentId = utils.uuid();

/**
 * Default statistics data structure with all values initialized to 0
 */
const defaultStatisticsData: TaskCount = {
  actualWorkload: 0,
  designNum: 0,
  bugNum: 0,
  canceledNum: 0,
  completedNum: 0,
  completedWorkload: 0,
  confirmingNum: 0,
  evalWorkload: 0,
  savingWorkload: 0,
  savingWorkloadRate: 0,
  functionalNum: 0,
  inProgressNum: 0,
  oneTimePassedNum: 0,
  oneTimePassedRate: 0,
  overdueNum: 0,
  overdueRate: 0,
  pendingNum: 0,
  perfNum: 0,
  processFailCount: 0,
  processCount: 0,
  requirementNum: 0,
  stabilityNum: 0,
  storyNum: 0,
  taskNum: 0,
  testFailNum: 0,
  testSuccessNum: 0,
  totalStatusNum: 0,
  totalTaskNum: 0,
  totalTaskTypeNum: 0,
  totalTestTypeNum: 0,
  validTaskNum: 0,
  progress: '0'
};

const statisticsData = ref<TaskCount>({ ...defaultStatisticsData });

/**
 * Determines the active key for the collapse component based on collapse state
 */
const activeKey = computed(() => {
  if (props.collapse) {
    return '';
  }
  return componentId;
});

/**
 * Loads statistics data from the API
 * <p>
 * Constructs request parameters and calls the analysis API to fetch task statistics.
 * Updates the loading state and statistics data based on the response.
 */
const loadStatisticsData = async (): Promise<void> => {
  emit('update:loading', true);

  let requestParams: RequestParams = {
    projectId: props.projectId
  };

  // Merge additional parameters if provided
  if (props.params) {
    requestParams = { ...requestParams, ...props.params };
  }

  const [error, response] = await analysis.getTaskCount(requestParams);
  emit('update:loading', false);

  if (error) {
    return;
  }

  if (response?.data) {
    statisticsData.value = response.data;
  }
};

// Lifecycle Hooks
onMounted(() => {
  // Watch for changes in filter parameters
  watch(() => props.params, (newValue) => {
    if (!newValue) {
      return;
    }
    loadStatisticsData();
  }, { immediate: false });

  // Watch for notification changes to trigger data refresh
  watch(() => props.notify, (newValue) => {
    if (newValue === undefined || newValue === null || newValue === '') {
      return;
    }
    loadStatisticsData();
  }, { immediate: true });
});
</script>

<template>
  <!-- Statistics panel with collapsible functionality -->
  <Collapse
    v-model:activeKey="activeKey"
    ghost
    collapsible="disabled">
    <CollapsePanel :key="componentId" :showArrow="false">
      <!-- Statistics cards section -->
      <Count :dataSource="statisticsData" class="statistics-cards" />
      <!-- ECharts section -->
      <Chart :dataSource="statisticsData" />
    </CollapsePanel>
  </Collapse>
</template>

<style scoped>
.ant-collapse :deep(.ant-collapse-item) .ant-collapse-header {
  display: none;
}

.ant-collapse :deep(.ant-collapse-content) .ant-collapse-content-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0;
}
</style>
